<!-- 商品发布 - 库存价格 - 属性列表 -->
<template>
  <div class="specifications">
    <draggable
      :animation="300"
      group="specifications"
      :disabled="attributeList.length < 2"
      :list="attributeList"
      handle=".move-icon"
      @end="onMoveSpec"
      item-key="index"
    >
      <template #item="{ element, index }">
        <div class="specifications-item active">
          <!-- <el-tooltip content="拖动排序"> -->
          <Icon
            icon="ic:round-drag-indicator"
            class="move-icon cursor-move"
            style="color: #8a909c"
          />
          <!-- </el-tooltip> -->
          <!-- <el-tooltip content="删除"> -->
          <Icon
            icon="ep:circle-close"
            class="del cursor-pointer text-red-5"
            @click="handleCloseProperty(index)"
          />
          <!-- </el-tooltip> -->
          <div class="specifications-item-box">
            <div class="lineBox"></div>
            <div class="specifications-item-name mb-18px">
              <el-input
                v-model="element.name"
                placeholder="规格名称"
                @change="attrChangeValue(element)"
                class="specifications-item-name-input"
                maxlength="10"
                show-word-limit
              />
            </div>
            <div class="rulesBox ml-30px">
              <draggable
                :animation="300"
                :disabled="element.values.length < 2"
                :list="element.values"
                handle=".drag"
                @end="onMoveSpec"
                item-key="index"
                class="item"
              >
                <template #item="{ element: child, index: childIndex }">
                  <div class="spec drag">
                    <el-tooltip content="删除">
                      <Icon
                        icon="ep:circle-close"
                        class="el-icon-error cursor-pointer text-red-5"
                        @click="handleCloseValue(index, childIndex)"
                      />
                    </el-tooltip>

                    <el-input
                      style="width: 120px"
                      v-model="child.name"
                      placeholder="规格值"
                      maxlength="10"
                      class="ml-10px"
                      @change="attrDetailChangeValue(child)"
                    >
                      <template #prefix>
                        <Icon
                          icon="ic:round-drag-indicator"
                          class="cursor-move"
                          style="color: #8a909c"
                        />
                      </template>
                    </el-input>
                  </div>
                </template>
              </draggable>
              <el-input
                :ref="setInputRef"
                v-show="inputVisible(index)"
                v-model="inputValue"
                class="!w-30 ml-10px"
                filterable
                size="default"
                @blur="handleInputConfirm(index, element.id)"
                @change="handleInputConfirm(index, element.id)"
                @keyup.enter="handleInputConfirm(index, element.id)"
              />

              <el-button
                v-show="!inputVisible(index)"
                class="button-new-tag ml-10px"
                size="default"
                @click="showInput(index)"
              >
                + 添加规格值
              </el-button>
            </div>
          </div>
        </div>
      </template>
    </draggable>
  </div>
</template>

<script lang="ts" setup>
import * as PropertyApi from '@/api/mall/product/property'
import { PropertyAndValues } from '@/views/mall/product/spu/components'
import { propTypes } from '@/utils/propTypes'
import draggable from 'vuedraggable'
import { generateSortNumericUUID } from '@/utils'
import { Property, Spu } from '@/api/mall/product/spu'

defineOptions({ name: 'ProductAttributes' })

const message = useMessage() // 消息弹窗
const inputValue = ref('') // 输入框值
const attributeIndex = ref<number | null>(null) // 获取焦点时记录当前属性项的index
// 输入框显隐控制
const inputVisible = computed(() => (index: number) => {
  if (attributeIndex.value === null) return false
  if (attributeIndex.value === index) return true
})
const inputRef = ref<any[]>([]) //标签输入框Ref
/** 解决 ref 在 v-for 中的获取问题*/
const setInputRef = (el: any) => {
  if (el === null || typeof el === 'undefined') return
  // 如果不存在 id 相同的元素才添加
  if (!inputRef.value.some((item) => item.inputRef?.attributes.id === el.inputRef?.attributes.id)) {
    inputRef.value.push(el)
  }
}
const attributeList = ref<PropertyAndValues[]>([]) // 商品属性列表
const attributeOptions = ref([] as PropertyApi.PropertyValueVO[]) // 商品属性名称下拉框
const props = defineProps({
  propertyList: {
    type: Array,
    default: () => {}
  },
  propFormData: {
    type: Object as PropType<Spu>,
    default: () => {}
  },
  isDetail: propTypes.bool.def(false) // 是否作为详情组件
})
const formData: Ref<Spu | undefined> = ref<Spu>() // 表单数据

/**
 * 将传进来的值赋值给 skuList
 */
watch(
  () => props.propFormData,
  (data) => {
    if (!data) return
    formData.value = data
  },
  {
    deep: true,
    immediate: true
  }
)
watch(
  () => props.propertyList,
  (data) => {
    if (!data) return
    attributeList.value = data as any
  },
  {
    deep: true,
    immediate: true
  }
)

// 规格名称改变
const attrChangeValue = (item: any) => {
  console.log(attributeList.value)
  formData.value!.skus.forEach((element) => {
    element.properties?.forEach((ele) => {
      if (ele.propertyId == item.id) {
        ele.propertyName = item.name
      }
      console.log(ele)
    })
  })
  // generateTableData(attributeList.value)
  // emit('success', attributeList.value)
  // 1.1 重复添加校验
  // for (const attrItem of attributeList.value) {
  //   if (attrItem.name === val) {
  //     return message.error('该属性已存在，请勿重复添加')
  //   }
  // }
}
// 规格值改变

const attrDetailChangeValue = (item: any) => {
  console.log(item)
  console.log(attributeList.value)
  formData.value!.skus!.forEach((element) => {
    element.properties?.forEach((ele) => {
      if (ele.valueId == item.id) {
        ele.valueName = item.name
      }
      console.log(ele)
    })
  })
  console.log(formData.value)

  // 1. 重复添加校验
  //   if (attributeList.value[index].values.find((item) => item.name === inputValue.value)) {
  //     message.warning('已存在相同属性值，请重试')
  //     attributeIndex.value = null
  //     inputValue.value = ''
  //     return
  // }
  // console.log(attributeList.value[index].values)
  // emit('success', attributeList.value)
}
// 规格拖拽排序后
const onMoveSpec = () => {
  generateTableData(attributeList.value)
}
/**生成规格项数据 进行排序 */
/** 构建所有排列组合 */
const build = (propertyValuesList: Property[][]) => {
  if (propertyValuesList.length === 0) {
    return []
  } else if (propertyValuesList.length === 1) {
    return propertyValuesList[0]
  } else {
    const result: Property[][] = []
    const rest = build(propertyValuesList.slice(1))
    for (let i = 0; i < propertyValuesList[0].length; i++) {
      for (let j = 0; j < rest.length; j++) {
        // 第一次不是数组结构，后面的都是数组结构
        if (Array.isArray(rest[j])) {
          result.push([propertyValuesList[0][i], ...rest[j]])
        } else {
          result.push([propertyValuesList[0][i], rest[j]])
        }
      }
    }
    return result
  }
}
const arraysEqual = (arr1, arr2) => {
  // 将数组转换为对象
  const obj1 = arr1.reduce((acc, cur) => {
    acc[JSON.stringify(cur)] = true
    return acc
  }, {})

  const obj2 = arr2.reduce((acc, cur) => {
    acc[JSON.stringify(cur)] = true
    return acc
  }, {})

  // 比较两个对象是否相等
  const keys1 = Object.keys(obj1)
  const keys2 = Object.keys(obj2)

  if (keys1.length !== keys2.length) {
    return false
  }

  for (let key of keys1) {
    if (!(key in obj2)) {
      return false
    }
  }

  return true
}
/** 生成表数据 */
const generateTableData = (propertyList: any[]) => {
  // 构建数据结构
  const propertyValues = propertyList.map((item) =>
    item.values.map((v: any) => ({
      propertyId: item.id,
      propertyName: item.name,
      valueId: v.id,
      valueName: v.name
    }))
  )
  const buildSkuList = build(propertyValues)
  console.log(buildSkuList)
  console.log(formData.value?.skus)

  // 将sku属性值替换为新的属性
  formData.value?.skus?.forEach((sku, index) => {
    buildSkuList.forEach((skuProPerties) => {
      let properties = Array.isArray(skuProPerties) ? skuProPerties : [skuProPerties]

      if (arraysEqual(properties, sku.properties)) {
        sku.properties = Array.isArray(skuProPerties) ? skuProPerties : [skuProPerties]
      }
    })
  })
  // 根据新顺序的属性 进行排序
  formData.value?.skus?.sort((a, b) => {
    const indexA = buildSkuList.findIndex(
      (item) => JSON.stringify(Array.isArray(item) ? item : [item]) === JSON.stringify(a.properties)
    )
    const indexB = buildSkuList.findIndex(
      (item) => JSON.stringify(Array.isArray(item) ? item : [item]) === JSON.stringify(b.properties)
    )

    return indexA - indexB
  })
  console.log(formData.value?.skus)
}

/** 删除属性值*/
const handleCloseValue = (index: number, valueIndex: number) => {
  let val = attributeList.value[index]!.values![valueIndex]!
  if (val) {
    for (let i = 0; i < formData.value!.skus!.length; i++) {
      let item = formData.value!.skus![i]
      if (
        item.properties &&
        item.properties.some((pI) => {
          return pI.valueId == val.id
        })
      ) {
        formData.value!.skus!.splice(i, 1)
        i--
      }
    }
  }
  attributeList.value[index].values?.splice(valueIndex, 1)

  // generateTableData(attributeList.value)
  // emit('success', attributeList.value)
}

/** 删除属性*/
const handleCloseProperty = (index: number) => {
  attributeList.value?.splice(index, 1)
  emit('success', attributeList.value)
}

/** 显示输入框并获取焦点 */
const showInput = async (index: number) => {
  attributeIndex.value = index
  inputRef.value[index].focus()
  // 获取属性下拉选项
  // await getAttributeOptions(attributeList.value[index].id)
}

/** 输入框失去焦点或点击回车时触发 */
const emit = defineEmits(['success']) // 定义 success 事件，用于操作成功后的回调
const handleInputConfirm = async (index: number, propertyId: number) => {
  console.log(attributeList.value)
  if (inputValue.value) {
    // 1. 重复添加校验
    if (attributeList.value[index].values.find((item) => item.name === inputValue.value)) {
      message.warning('已存在相同属性值，请重试')
      attributeIndex.value = null
      inputValue.value = ''
      return
    }

    // 2.2 情况二：新属性值，则进行保存
    try {
      const id = generateSortNumericUUID()
      attributeList.value[index].values.push({ id, name: inputValue.value })
      // message.success(t('common.createSuccess'))
      emit('success', attributeList.value)
    } catch {
      message.error('添加失败，请重试')
    }
  }
  attributeIndex.value = null
  inputValue.value = ''
}
</script>
<style lang="scss" scoped>
.specifications {
  width: 100%;
  .specifications-item:hover {
    background-color: var(--el-color-primary-light-9);
  }

  .specifications-item:hover .del {
    display: block;
  }

  .specifications-item:last-child {
    margin-bottom: 14px;
  }

  .specifications-item {
    position: relative;
    display: flex;
    align-items: center;
    padding: 20px 15px;
    transition: all 0.1s;
    margin-bottom: 10px;
    border-radius: 4px;

    .del {
      display: none;
      position: absolute;
      right: 15px;
      top: 15px;
      font-size: 22px;
      color: var(--prev-color-primary);
      cursor: pointer;
      z-index: 9;
    }

    .specifications-item-box {
      position: relative;

      .lineBox {
        position: absolute;
        left: 13px;
        top: 30px;
        width: 30px;
        height: 45px;
        border-radius: 6px;
        border-left: 1px solid #dcdfe6;
        border-bottom: 1px solid #dcdfe6;
      }

      .specifications-item-name {
        .el-icon-info {
          color: var(--prev-color-primary);
          font-size: 12px;
          margin-left: 5px;
        }
      }

      .specifications-item-name-input {
        width: 200px;
      }
    }
  }
}

.spec {
  display: block;
  margin: 5px 0;
  position: relative;

  .el-icon-error {
    position: absolute;
    display: none;
    right: -3px;
    top: -3px;
    z-index: 9;
    color: var(--el-color-primary);
  }
}
.spec:hover {
  .el-icon-error {
    display: block;
    z-index: 999;
    cursor: pointer;
  }
}
.rulesBox {
  display: flex;
  flex-wrap: wrap;
  align-items: center;

  .item {
    display: flex;
    flex-wrap: wrap;
  }

  .addfont {
    margin-top: 5px;
    margin-left: 0px;
  }

  :deep .el-popover {
    border: none;
    box-shadow: none;
    padding: 0;
    margin-top: 5px;
    line-height: 1.5;
  }
}
</style>
